package cn.edu.fzu.homemaking.sso.controller;

import cn.edu.fzu.homemaking.common.MD5Util;
import cn.edu.fzu.homemaking.common.SessionConstant;
import cn.edu.fzu.homemaking.sso.api.WalletApi;
import cn.edu.fzu.homemaking.sso.domain.enums.SexEnum;
import cn.edu.fzu.homemaking.sso.service.LoginService;
import cn.edu.fzu.homemaking.web.Result;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

@Api(tags = "SSO-登陆模块")
@RestController
@RequestMapping("/api/sso/")
public class LoginController {

    @Value("${login.url}")
    private String       loginUrl;

    @Resource
    private LoginService loginService;

    @Resource
    private WalletApi    walletApi;

    @GetMapping("/index")
    public Result index(String sessionId) {
        StringBuilder builder = new StringBuilder(loginUrl);
        if (StringUtils.isNotBlank(sessionId)) {
            builder.append("?").append(SessionConstant.DSESSIONID).append("=").append(sessionId);
        }
        return new Result(builder.toString());
    }


    @ApiOperation(value = "密码登陆接口")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", required = true, value = "邮箱"),
            @ApiImplicitParam(name = "password", required = true, value = "密码"),
            @ApiImplicitParam(name = "code", required = true, value = "图形验证码") })
    @PostMapping("/login")
    public Result login(@RequestParam String email, @RequestParam String password, @RequestParam String code,
                        HttpServletRequest request) {
        HttpSession session = request.getSession();
        loginService.login(email, password, code, session);
        Map<String, Object> token = token(session);
        walletApi.initWater();
        return new Result(token);
    }


    @ApiOperation(value = "人脸登陆接口")
    @PostMapping("/faceLogin")
    public Result faceLogin(MultipartHttpServletRequest request) throws IOException {
        HttpSession session = request.getSession();
        loginService.faceLogin(Base64Utils.encodeToString(Objects.requireNonNull(request.getFile("file")).getBytes()),
                session);
        Map<String, Object> token = token(session);
        walletApi.initWater();
        return new Result(token);
    }


    @ApiOperation(value = "获取图形验证码接口")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", required = true, value = "邮箱") })
    @GetMapping("/codeImg")
    public Result emailCode(@RequestParam String email, HttpServletRequest request) throws IOException {
        return new Result(loginService.imgCode(email, request.getSession()));
    }


    @ApiOperation(value = "登出接口")
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        walletApi.dropWater();
        loginService.logout(request.getSession());
        return Result.SUCCESS;
    }


    @ApiOperation(value = "用户注册接口")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", required = true, value = "邮箱"),
            @ApiImplicitParam(name = "password", required = true, value = "密码"),
            @ApiImplicitParam(name = "name", required = true, value = "姓名"),
            @ApiImplicitParam(name = "sex", required = true, value = "性别"),
            @ApiImplicitParam(name = "birth", required = true, value = "出生年月:yyyy-MM-dd"),
            @ApiImplicitParam(name = "phone", required = true, value = "手机号"),
            @ApiImplicitParam(name = "address", required = true, value = "家庭地址"),
            @ApiImplicitParam(name = "faceUrl", required = true, value = "人脸照片"),
            @ApiImplicitParam(name = "code", required = true, value = "邮箱验证码") })
    @PostMapping("/register")
    public Result register(@RequestParam String email, @RequestParam String password, @RequestParam String name,
                           @RequestParam SexEnum sex, @RequestParam Date birth, @RequestParam String phone,
                           @RequestParam String address, @RequestParam String faceUrl, @RequestParam String code,
                           HttpServletRequest request) {
        loginService.register(email, password, name, sex, birth, phone, address, faceUrl, code, request.getSession());
        return Result.SUCCESS;
    }


    @ApiOperation(value = "修改密码")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", required = true, value = "邮箱"),
            @ApiImplicitParam(name = "code", required = true, value = "邮箱验证码"),
            @ApiImplicitParam(name = "password", required = true, value = "新密码") })
    @PostMapping("/updatePassword")
    public Result updatePassword(String email, String code, String password, HttpServletRequest request) {
        loginService.updatePassword(email, code, password, request.getSession());
        return Result.SUCCESS;
    }


    @ApiOperation(value = "公司用户注册接口")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", required = true, value = "邮箱"),
            @ApiImplicitParam(name = "password", required = true, value = "密码"),
            @ApiImplicitParam(name = "name", required = true, value = "姓名"),
            @ApiImplicitParam(name = "sex", required = true, value = "性别"),
            @ApiImplicitParam(name = "birth", required = true, value = "出生年月:yyyy-MM-dd"),
            @ApiImplicitParam(name = "phone", required = true, value = "手机号"),
            @ApiImplicitParam(name = "address", required = true, value = "家庭地址"),
            @ApiImplicitParam(name = "faceUrl", required = true, value = "人脸照片"),
            @ApiImplicitParam(name = "code", required = true, value = "邮箱验证码"),
            @ApiImplicitParam(name = "companyName", required = true, value = "公司名称"),
            @ApiImplicitParam(name = "creditCode", required = true, value = "公司统一信用代码"),
            @ApiImplicitParam(name = "legalPerson", required = true, value = "公司法定代表人"),
            @ApiImplicitParam(name = "businessLicense", required = true, value = "公司营业执照"),
            @ApiImplicitParam(name = "contact", required = true, value = "公司联系人"),
            @ApiImplicitParam(name = "companyPhone", required = true, value = "公司联系电话"),
            @ApiImplicitParam(name = "areaId", required = true, value = "地区id"),
            @ApiImplicitParam(name = "companyAddress", required = true, value = "公司详细地址"), })
    @PostMapping("/registerCompany")
    public Result registerCompany(@RequestParam String email, @RequestParam String password, @RequestParam String name,
                                  @RequestParam SexEnum sex, @RequestParam Date birth, @RequestParam String phone,
                                  @RequestParam String address, @RequestParam String faceUrl, @RequestParam String code,
                                  @RequestParam String companyName, @RequestParam String creditCode,
                                  @RequestParam String legalPerson, @RequestParam String businessLicense,
                                  @RequestParam String contact, @RequestParam String companyPhone,
                                  @RequestParam Long areaId, @RequestParam String companyAddress,
                                  HttpServletRequest request) {
        loginService.registerCompanyAdmin(email, password, name, sex, birth, phone, address, faceUrl, code, companyName,
                creditCode, legalPerson, businessLicense, contact, companyPhone, areaId, companyAddress,
                request.getSession());
        return Result.SUCCESS;
    }


    @ApiOperation(value = "上传人脸接口")
    @PostMapping("/uploadFace")
    public Result upload(MultipartHttpServletRequest request) {
        return new Result(loginService.uploadFace(request.getFile("file")));
    }


    @ApiOperation(value = "获取邮箱验证码", httpMethod = "GET")
    @ApiImplicitParams({ @ApiImplicitParam(name = "email", value = "邮箱") })
    @GetMapping("/sendEmailCode")
    public Result sendEmailCode(@RequestParam String email, HttpServletRequest request) {
        loginService.sendEmailCode(email, request.getSession());
        return Result.SUCCESS;
    }


    @ApiOperation(value = "获取session中的属性值", httpMethod = "GET")
    @ApiImplicitParams({ @ApiImplicitParam(name = "param", value = "属性名") })
    @GetMapping("/getSessionAttribute")
    public Result getSessionAttribute(@RequestParam String param, HttpServletRequest request) {
        return new Result(request.getSession().getAttribute(param));
    }


    @ApiOperation(value = "获取session中的属性值", httpMethod = "GET")
    @ApiImplicitParams({ @ApiImplicitParam(name = "key", value = "属性名"),
            @ApiImplicitParam(name = "value", value = "属性名") })
    @GetMapping("/setSessionAttribute")
    public Result setSessionAttribute(@RequestParam String key, @RequestParam Object value,
                                      HttpServletRequest request) {
        request.getSession().setAttribute(key, value);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "是否登陆", httpMethod = "GET")
    @GetMapping("/isLogin")
    public Result isLogin(HttpServletRequest request) {
        return new Result(request.getSession().getAttribute(SessionConstant.ACCOUNT) != null);
    }


    private Map<String, Object> token(HttpSession session) {
        //防止被攻击，使用token校验
        String token = MD5Util.MD5Encode(session.getId() + System.currentTimeMillis());
        session.setAttribute(SessionConstant.TOKEN, token);

        Map<String, Object> map = Maps.newHashMapWithExpectedSize(2);
        map.put(SessionConstant.TOKEN, token);

        String redirectUrl = (String) session.getAttribute(SessionConstant.REDIRECT_URL);
        if (StringUtils.isBlank(redirectUrl)) {
            String userType = (String) session.getAttribute(SessionConstant.USER_TYPE);
            switch (userType) {
                case SessionConstant.USER:
                    redirectUrl = "http://47.120.40.248/#/?" + SessionConstant.DSESSIONID + "=" + session.getId();
                    break;
                case SessionConstant.COMPANY:
                    redirectUrl = "http://8.130.52.6/#/?" + SessionConstant.DSESSIONID + "=" + session.getId();
                    break;
                case SessionConstant.SYS_USER:
                    redirectUrl = "http://47.120.7.70/#/?" + SessionConstant.DSESSIONID + "=" + session.getId();
                    break;
            }
        }
        map.put(SessionConstant.REDIRECT_URL, redirectUrl);
        return map;
    }
}
